
/**
//player.c
**/

#include <stdbool.h>
#include <stdint.h>
#include "nrf_log.h"
#include "nrf_delay.h"
#include "wm8978.h"
#include "nrf_drv_i2s.h"
#include "player.h"

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

#include "flash_manage.h"
#include "w25q128.h"

#define I2S_TX_BUF_SIZE    (1024 * 5)


/* 播放状态 */
enum
{
	STA_IDLE = 0,	/* 待机状态 */
	STA_RECORDING,	/* 录音状态 */
	STA_PLAYING,	/* 放音状态 */
	STA_ERR,			/*  error  */
};

/* 播放操作 */
enum
{
	PLAY_IDLE = 0,	        /*  */
	PLAY_START,	            /* 开始播放 */
	PLAY_STOP,	            /* 停止播放 */
	PLAY_PREPARE_DATA,	    /* 停止播放 */
};

typedef struct
{
	uint8_t ucStatus;			/* 录音机状态，0表示待机，1表示录音中，2表示播放中 */	
	uint8_t Isread;             /* DMA传输完成标志 */
	uint8_t bufflag;            /* 数据缓存区选择标志 */
}PLAYE_DEV_T;	

#pragma pack(1)

typedef struct
{
    uint8_t         u8Event;
    uint8_t         u8Parameter1;
} AUDIO_PLAY_EVENT_MSG;

typedef struct
{
    voice_index_t   u8voice_index;      //语音索引/编号
    uint32_t        u32addr;            //语音在flash中的存储位置
    uint32_t        u32size;            //语音大小
}voice_mng_t;

#pragma pack()

const voice_mng_t voice_mng_info[] = 
{
    {
        .u8voice_index  = yuandigongbu_meizu10cikaishi,
        .u32addr        = 0x0,
        .u32size        = 0x27618,
    },

    {
        .u8voice_index  = yuandigongbu_meizu15cikaishi,
        .u32addr        = 0x27618,
        .u32size        = 0x26F74,
    },

    {
        .u8voice_index  = yuandigongbu_meizu20cikaishi,
        .u32addr        = 0x4E58C,
        .u32size        = 0x27636,
    },

    {
        .u8voice_index  = yuandigongbu_wcbzxlqxx5fz,
        .u32addr        = 0x75BC2,
        .u32size        = 0x16F00,
    },

    {
        .u8voice_index  = yuandigongbu_xxsjjsrwmksxyzxl,
        .u32addr        = 0x8CAC2,
        .u32size        = 0x1A294,
    },

    {
        .u8voice_index  = yuandigongbu_zbxljsl,
        .u32addr        = 0xA6D56,
        .u32size        = 0xE79E,
    },

    {
        .u8voice_index  = houdengtui_houdengpao4zukaishi,
        .u32addr        = 0xB54F4,
        .u32size        = 0x1B306,
    },

    {
        .u8voice_index  = houdengtui_houdengpao6zukaishi,
        .u32addr        = 0xD07FA,
        .u32size        = 0x1B5E2,
    },

    {
        .u8voice_index  = houdengtui_houdengpao8zukaishi,
        .u32addr        = 0xEBDDC,
        .u32size        = 0x1B0C4,
    },

    {
        .u8voice_index  = houdengtui_wcbzxlqfszhqdzbxyz,
        .u32addr        = 0x106EA0,
        .u32size        = 0x2037A,
    },

    {
        .u8voice_index  = houdengtui_yzhqdrwmksxyzxl,
        .u32addr        = 0x12721A,
        .u32size        = 0x183A2,
    },

    {
        .u8voice_index  = houyangzhitui_5zukaishi,
        .u32addr        = 0x13F5BC,
        .u32size        = 0x1D1D4,
    },

    {
        .u8voice_index  = houyangzhitui_6zukaishi,
        .u32addr        = 0x15C790,
        .u32size        = 0x1DB8E,
    },

    {
        .u8voice_index  = houyangzhitui_8zukaishi,
        .u32addr        = 0x17A31E,
        .u32size        = 0x1DC5E,
    },

    {
        .u8voice_index  = xingjinjianhou_xjjhttks,
        .u32addr        = 0x197F7C,
        .u32size        = 0x236D2,
    },

    {
        .u8voice_index  = xingjinjiangao_xjjksgttks,
        .u32addr        = 0x1BB64E,
        .u32size        = 0x22C1C,
    },

    {
        .u8voice_index  = xingjinjianjiao_xjjjcbks,
        .u32addr        = 0x1DE26A,
        .u32size        = 0x1EB64,
    },

    {
        .u8voice_index  = biansupao_bsp4zmz200mxzks,
        .u32addr        = 0x1FCDCE,
        .u32size        = 0x1B58E,
    },
    
    {
        .u8voice_index  = biansupao_kaishikuaisupao,
        .u32addr        = 0x21835C,
        .u32size        = 0x8D34,
    },

    {
        .u8voice_index  = biansupao_kaishimansupao,
        .u32addr        = 0x221090,
        .u32size        = 0x9794,
    },

    {
        .u8voice_index  = biansupao_wcyzxxyxb,
        .u32addr        = 0x22A824,
        .u32size        = 0x10260,
    },

    {
        .u8voice_index  = biansupao_xxjsqjxxlb,
        .u32addr        = 0x23AA84,
        .u32size        = 0x12AD0,
    },

    {
        .u8voice_index  = kuabutiao_meizu30mi,
        .u32addr        = 0x24D554,
        .u32size        = 0x1AC6E,
    },

    {
        .u8voice_index  = kuabutiao_meizu40mi,
        .u32addr        = 0x2681C2,
        .u32size        = 0x1A9DE,
    },

    {
        .u8voice_index  = kuabutiao_meizu50mi,
        .u32addr        = 0x282BA0,
        .u32size        = 0x19AE8,
    },

    {
        .u8voice_index  = nanzi1000mi_xianzaikaishi,
        .u32addr        = 0x29C688,
        .u32size        = 0x1F13A,
    },

    {
        .u8voice_index  = nanzi1000mi_400miwancheng,
        .u32addr        = 0x2BB7C2,
        .u32size        = 0x20C7E,
    },
    
    {
        .u8voice_index  = nanzi1000mi_xxjsqjx200mxl,
        .u32addr        = 0x2DC440,
        .u32size        = 0x15766,
    },

    {
        .u8voice_index  = nanzi1000mi_200miwancheng,
        .u32addr        = 0x2F1BA6,
        .u32size        = 0x144BE,
    },

    {
        .u8voice_index  = nanzi1000mi_gxnwcxl,
        .u32addr        = 0x306064,
        .u32size        = 0xD404,
    },

    {
        .u8voice_index  = nvzi1000mi_kaishi,
        .u32addr        = 0x313468,
        .u32size        = 0x1EA1E,
    },

    {
        .u8voice_index  = nvzi1000mi_400mwcxxyxb,
        .u32addr        = 0x331E86,
        .u32size        = 0x20D58,
    },

    {
        .u8voice_index  = nvzi1000mi_200miwancheng,
        .u32addr        = 0x352BDE,
        .u32size        = 0x1440E,
    },

    {
        .u8voice_index  = yiqianmiceyan_kaishi,
        .u32addr        = 0x366FEC,
        .u32size        = 0x1769C,
    },

    {
        .u8voice_index  = yiqianmiceyan_jieshu,
        .u32addr        = 0x37E688,
        .u32size        = 0x1C5A6,
    },

    {
        .u8voice_index  = yiqianmiceyan_qbcdqzt,
        .u32addr        = 0x39AC2E,
        .u32size        = 0x116B2,
    },

    {
        .u8voice_index  = yiqianmiceyan_zaijianchiyixia,
        .u32addr        = 0x3AC2E0,
        .u32size        = 0x8C10,
    },
};


uint8_t voice_buf[512*4]   = {0};
bool voice_buf_ready        = false;

extern TimerHandle_t timer_50ms;               //20hz timer

static QueueHandle_t Queue_audio_play_msg = NULL;

uint32_t voice_read_len = 0;

static voice_index_t current_play_index = voice_max;


//*****************************************************************************
// * 函 数 名  : Player_Stop
// * 函数功能  : 停止播放
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void Player_Stop(void)
{
    ret_code_t err_code;
    
    //停止周期定时器
    err_code = xTimerStop(timer_50ms, 0);
    if (pdPASS != err_code)
    {
        APP_ERROR_HANDLER(err_code);
    }

	Player_I2S_Stop();

	wm8978_Reset();	/* 复位WM8978到复位状态 */
	
}

//*****************************************************************************
// * 函 数 名  : timer_50ms_handle
// * 函数功能  : 50ms周期定时器
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void timer_50ms_handle(TimerHandle_t xTimer)
{
    UNUSED_PARAMETER(xTimer);
    
    if (false == voice_buf_ready)
    {
        uint32_t u32read_addr   = SPI_FLASH_VOICE_DATA_ADDR_START + voice_mng_info[current_play_index].u32addr + 44 + voice_read_len;
        uint32_t u32read_len    = 512*4;
        
        Flash_Read(voice_buf, u32read_addr, u32read_len);

        voice_buf_ready = true;
    }
}


//*****************************************************************************
// * 函 数 名  : audio_play
// * 函数功能  : 播放指定音频
// * 输入参数  :	 voice_index:音频索引
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void audio_play(uint8_t voice_index)
{
    NRF_LOG_INFO("audio_play");
    
    AUDIO_PLAY_EVENT_MSG Message = {0};
    
    Message.u8Event         = PLAY_START;
    Message.u8Parameter1    = voice_index;

    //发出消息
    if (NULL != Queue_audio_play_msg)
    {
        xQueueSend(Queue_audio_play_msg, &Message, 0);
    }
}

static ret_code_t Player_Start(void)
{
    ret_code_t err_code;
    
    voice_buf_ready = false;
    voice_read_len = 0;

    // 启动运动用定时器
    err_code = xTimerStart(timer_50ms, 0);
    if (pdPASS != err_code)
    {
        APP_ERROR_HANDLER(err_code);
    }

	nrf_delay_ms(10);	/* 延迟一段时间，等待I2S中断结束 */
	Player_I2S_Stop();	/* 停止I2S录音和放音 */
	wm8978_Reset();		/* 复位WM8978到复位状态 */	
	
	/* 配置WM8978芯片，输入为DAC，输出为耳机 */
//	wm8978_CfgAudioPath(DAC_ON, EAR_LEFT_ON | EAR_RIGHT_ON);
	wm8978_CfgAudioPath(DAC_ON, SPK_ON);
	/* 调节音量，左右相同音量 */
	wm8978_SetOUT1Volume(63);
	wm8978_SetOUT2Volume(63);
	/* 配置WM8978音频接口为飞利浦标准I2S接口，16bit */
	wm8978_CfgAudioIF(I2S_Standard_Phillips, 16);


	return Player_I2S_Start();
}

//*****************************************************************************
// * 函 数 名  : task_audio_play_handle
// * 函数功能  : 语音播放任务处理
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void task_audio_play_handle(void * arg)
{
    UNUSED_PARAMETER(arg);
    
    AUDIO_PLAY_EVENT_MSG EventMsg = {0};

    uint32_t rec = 0;

    Queue_audio_play_msg = xQueueCreate(3, sizeof(AUDIO_PLAY_EVENT_MSG));

    current_play_index = voice_max;

    while (1)
    {
        rec = xQueueReceive(Queue_audio_play_msg, &EventMsg, 100/portTICK_PERIOD_MS);
        
        if (pdPASS == rec)
        {
        
            NRF_LOG_INFO("xQueueReceive: u8Event = %d", EventMsg.u8Event);
            //播放
            if (PLAY_START == EventMsg.u8Event)
            {
                current_play_index = EventMsg.u8Parameter1;
                Player_Start();
            }
            //停止播放
            else if (PLAY_STOP == EventMsg.u8Event)
            {
                Player_Stop();
            }
            
            switch (EventMsg.u8Event)
            {
                case PLAY_START:
                {
                    current_play_index = EventMsg.u8Parameter1;
                    Player_Start();
                }
                break;
                
                case PLAY_STOP:
                {
                    Player_Stop();
                }
                break;
                
                case PLAY_PREPARE_DATA:
                {
                }
                break;
                
                default:
                break;
            }
        }
        
        EventMsg.u8Event        = 0;
        EventMsg.u8Parameter1   = 0;
    }
}

//*****************************************************************************
// * 函 数 名  : prepare_tx_data
// * 函数功能  : 准备I2S需要的发送的数据
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void prepare_tx_data(uint32_t * p_block, uint32_t u32buf_len)
{
    if (current_play_index >= voice_max)
    {
        Player_Stop();
        return;
    }
    
    if (voice_read_len + u32buf_len < voice_mng_info[current_play_index].u32size)
    {
    }
    else
    {
        voice_read_len = 0;
        Player_Stop();
        return;
    }
    
    if (voice_buf_ready)
    {
        memcpy((uint8_t*)p_block, voice_buf, u32buf_len);
        voice_read_len += u32buf_len;
        voice_buf_ready = false;
    }

}


